#include "StateFactory.h"
#include "ActionFactory.h"
#include "TransitionFactory.h"
#include "State.h"
#include "StateGraph.h"
#include "StateGraphData.h"

//-------------------------------------------------------------------------
CStateBase *CreateState(const CStateDataPtr &pStateData);
void ConfigState(CStateBase *pState, const CStateDataPtr &pStateData);
CStateGraph *CreateStateGraph(const CStateGraphDataPtr &pStateGraphData);
//-------------------------------------------------------------------------


//-------------------------------------------------------------------------
CStateBase *CStateFactory::Create(const CStateDataPtr &pStateData)
{
	CStateGraphDataPtr pStateGraphDataPtr = pStateData->DynamicCast<CStateGraphData>();

	if(pStateGraphDataPtr.IsValid())
	{
		return CreateStateGraph(pStateGraphDataPtr);
	}
	else
	{
		return CreateState(pStateData);
	}
}

//-------------------------------------------------------------------------
void ConfigState(CStateBase *pState, const CStateDataPtr &pStateData)
{
	for(u32_t i = 0; i < pStateData->GetSizeEntryActionData(); ++i)
	{
		pState->AddEntryAction(CActionFactory::Create(pStateData->GetEntryActionData(i)));
	}

	for(u32_t i = 0; i < pStateData->GetSizeExitActionData(); ++i)
	{
		pState->AddEntryAction(CActionFactory::Create(pStateData->GetExitActionData(i)));
	}

	for(u32_t i = 0; i < pStateData->GetSizeExitActionData(); ++i)
	{
		pState->AddExitAction(CActionFactory::Create(pStateData->GetExitActionData(i)));
	}

	for(u32_t i = 0; i < pStateData->GetSizeActionData(); ++i)
	{
		pState->AddAction(CActionFactory::Create(pStateData->GetActionData(i)));
	}

	for(u32_t i = 0; i < pStateData->GetSizeTransitionData(); ++i)
	{
		pState->AddTransition(CTransitionFactory::Create(pStateData->GetTransitionData(i)));
	}
}

//-------------------------------------------------------------------------
CStateBase *CreateState(const CStateDataPtr &pStateData)
{
	CState *pState = new CState(pStateData->GetName().c_str());
	ConfigState(pState, pStateData);
	return pState;
}

//-------------------------------------------------------------------------
CStateGraph *CreateStateGraph(const CStateGraphDataPtr &pStateGraphData)
{
	CStateGraph *pState = new CStateGraph(pStateGraphData->GetName().c_str());
	ConfigState(pState, pStateGraphData);

	for(u32_t i = 0; i < pStateGraphData->GetSizeStatesData(); ++i)
	{
		pState->AddState(CStateFactory::Create(pStateGraphData->GetStateData(i)));
	}

	pState->SetInitialState(CStateFactory::Create(pStateGraphData->GetInitialStateData()));

	return pState;
}
